<?php

/**
 * Store_FilterController
 * 
 * Модуль магазина, контроллер фильтра товаров
 * Фильтр товаров отображается внутри категории, и призван 
 * помочь юзернейму с выбором товаров
 * 
 * @package   Store
 * @author    Игорь Будасов aka Lord <igor.budasov@gmail.com> 
 * @copyright Игорь Будасов aka Lord <igor.budasov@gmail.com> 
 */
 
class Store_FilterController extends Lord_Controller_Action 
{   
	
/*------------------------------------------------------------------------------*/
		 
	/**
	 * Индексный метод. Отображает формочку фильтра
	 */
	 
	public function indexAction()
	{            
        // проверим, открыта ли у нас какая категория
        $cid  = $this->_checkCid();    
        
        /**
        * Секция получения данных для формочки фильтра
        */
             
        // если категория открыта - можно проверить производителей в ней
        $sPrices       = array();
        $sRatings      = array();            
        $manufacturers = array();
        $prices        = array();
        $ratings       = array();
        if($cid)
        {
            // достаем все категории и парсим для определения дочерних категорий
            $items = $this->model->getAllCategories()->toArray();
            $children = $this->_getChildren($items, $cid);        
            // для получения списка производителей товаров из категории, 
            // мы достанем продукты, но без сортировщика.
            $manufacturersList = array();
            // $sGoods -- продукты без сортировщика
            $sGoods = $this->model->getGoods($children, $cid);
            // если у нас товаров меньше чем на одну страницу - фильтр не будем показывать
            if(count($sGoods) < $this->_helper->config()->common->itemCountPerPage) return;
            //получаем производителей
            foreach($sGoods as $good)
            {
                $manufacturersList[$good->mid] = '';
                $prices[] = $good->price;
                $ratings[] = $good->rating;
            }
            $manufacturersData = $this->model->getManufacturers($manufacturersList);
            foreach($manufacturersData as $key=>$val)
            {
                $manufacturers[$val['id']] = $val['name'];
            }   
            // отсортируем производителей в алфавитном порядке
            asort($manufacturers);
            // цены - по возрастанию
            asort($prices);
            // рейтинг - по возрастанию
            $ratings = array_unique($ratings);
            asort($ratings);
            // в этом месте у нас получаются цены и рейтинги отсортированые
            // по возрастанию, но ключи не ок. Пока я напишу заглушку, но нужно переделать
            $i = 1;
            foreach($prices as $price)
            {
                $sPrices[$i] = $price;
                $i = $i+1;
            }
            $i = 1;
            foreach($ratings as $rating)
            {
                $sRatings[$i] = $rating;
                $i = $i+1;
            }
            /**
            * Получаем характеристики товаров и их значения,
            * если установлена настройка полного фильтра    
            */
             
            if($this->_helper->config()->filter == 1) 
            {
                // получаем свойства категории и дочерних категорий
                $properties = $this->model->getCategoryProperties($children)->toArray();
                // получаем значения свойств товаров
                foreach($properties as $k=>$property)
                {
                    $properties[$k]['values'] = $this->model->getPropertyValues($property['property_id'])->toArray();
                }
            }
            else $properties = array();
            
            
            /**
            * Обработка формы
            */
            //$data['cid'] = $cid;
            $cookie = $_COOKIE['Profit_Filter'];
            if($cookie)
            {
                $filter = $this->model->getFilter($cookie);
                $data = unserialize(base64_decode($filter->params));   
            }
            else
            {
                $data = array();
            }            
            $form = $this->_form($manufacturers, $data, $properties);
            // валидация
            if (!empty($_POST)) 
            {
                if (!$form->isValid($_POST)) 
                {   
                    // показываем сообщение об ошибке
                    $this->view->err = 'form_fail';
                    // получаем невалидные значения, введенные в форму         
                    $values = $form->getUnfilteredValues(); 
                    // получаем ошибки
                    $errors = $form->getErrors(); 
                    // показываем форму с невалидными данными
                    return $this->view->form = $this->_form($manufacturers, $values, $properties, $errors);
                }
            }

            // если к нам что-то пришло из поста
            if ($this->_request->isPost()) 
            {        
                // получаем корректные данные, введенные юзером
                $values = $form->getValues();
                $values['cid'] = $cid;
                // убедимся, что это именно фильтр отправил нам пост
                if(isset($values['filter_submit']))
                {
                    // сохраним полученные данные для составления запроса потом
                    $filterData['params'] = base64_encode(serialize($values));
                    $filterData['date'] = date('Y-m-d');
                    $filterId = $this->model->saveFilterParams($filterData);
                    
                    // теперь поставим куку, чтоб из контроллера товаров был виден наш фильтр
                    $ok = setcookie('Profit_Filter',          // имя куки
                                $filterId,                    // значение
                                time()+60*60*24*30,           // срок хранения
                                '/',                          // путь на сервере
                                '.' . $_SERVER['SERVER_NAME'] // имя сервера
                                );
                    $this->_redirect('store/goods/index/cid/'.$cid);
                }
            }
        }
                
        $this->view->form = $form;
        $this->view->prices = $sPrices;
        $this->view->ratings = $sRatings;
        $this->view->cid  = $cid;    
        $this->view->count  = count($sGoods);
                                   
        $this->view->price_from = array_search($data['price_from'], $sPrices);
        $this->view->price_to = array_search($data['price_to'], $sPrices);
        $this->view->rating_from = array_search($data['rating_from'], $sRatings);
        $this->view->rating_to = array_search($data['rating_to'], $sRatings);
        return;
	}

/*------------------------------------------------------------------------------*/

    public function clearAction()
    {
        
    }

/*==============================================================================*/
    
    /**
    * Приватный метод для построения формы
    * В качестве аргумента принимает уже заполненые 
    * данные (при редактировании)
    * 
    * @param $data array 
    * @param $errors array
    * @param $categories array
    * @return object
    */
    
    private function _form($manufacturers = array(), 
                           $data = array(), 
                           $properties = array(),
                           $errors = array())
    {       
       $cidValue = ($data['cid'])
                  ? $data['cid']
                  : $this->_getParam('cid'); 
        // обратите внимание, форма создается на основе собственного класса. 
        $form = new Lord_Form_Form(); 
        $form->setAction( '/' . $this->_moduleName .
                          '/' . $this->_controllerName .
                          '/index/cid/' . $cidValue)
             ->setMethod('post');
        
        // кодировка     
        $charset = $this->_helper->config()->common->charset;
        
        // Цена товара: начальная
        $priceFrom = new Lord_Form_Element_Text('price_from', array(
            'label'       => $this->view->translate('store_filter_form_price_from'),
            'maxlength'   => '10',
            'validators'  => array(
                array('StringLength', true, array(0, 10, $charset))
            ),
            'value'       => (!empty($data['price_from'])) ? $data['price_from'] : '' 
        ));
        $form->addElement($priceFrom);           
             
        // Цена товара: конечная
        $priceTo = new Lord_Form_Element_Text('price_to', array(
            'label'       => $this->view->translate('store_filter_form_price_to'),
            'maxlength'   => '10',
            'validators'  => array(
                array('StringLength', true, array(0, 10, $charset))
            ),
            'value'       => (!empty($data['price_to'])) ? $data['price_to'] : '' 
        ));
        $form->addElement($priceTo);
        
        // Обернем цены в филдсет
        $form->addDisplayGroup(
            array('price_from', 'price_to'), 'priceFieldsGroup',
            array('legend' => $this->view->translate('store_filters_form_prices'))
        );        
                
        // Рейтинг магазина: начальный
        $ratingFrom = new Lord_Form_Element_Text('rating_from', array(
            'label'       => $this->view->translate('store_filter_form_rating_from'),
            'maxlength'   => '2',
            'validators'  => array(
                array('StringLength', true, array(0, 2, $charset))
            ),
            'value'       => (!empty($data['rating_from'])) ? $data['rating_from'] : '' 
        ));
        $form->addElement($ratingFrom);             
                
        // Рейтинг магазина: конечный
        $ratingTo = new Lord_Form_Element_Text('rating_to', array(
            'label'       => $this->view->translate('store_filter_form_rating_to'),
            'maxlength'   => '2',
            'validators'  => array(
                array('StringLength', true, array(0, 2, $charset))
            ),
            'value'       => (!empty($data['rating_to'])) ? $data['rating_to'] : '' 
        ));
        $form->addElement($ratingTo);
        
        // Обернем рейтинг в филдсет
        $form->addDisplayGroup(
            array('rating_from', 'rating_to'), 'ratingFieldsGroup',
            array('legend' => $this->view->translate('store_filters_form_ratings'))
        );                
        
        // производители      
        if(!empty($manufacturers))
        {
            $manufacturersOptions = new Zend_Form_Element_MultiCheckbox('manufacturers', array(
                'label'        => $this->view->translate('store_filter_form_manufacturers'),
                'multiOptions' => $manufacturers,
                'value'        => (!empty($data['manufacturers'])) ? $data['manufacturers'] : $data['manufacturers'] = array()
            ));
            $form->addElement($manufacturersOptions);              
        }
                           
        // Есть ли товар на складе
        $stock = new Zend_Form_Element_Radio('stock', array(
            'label'       => $this->view->translate('store_filter_form_stock'),
            'multiOptions'=> array('1' => $this->view->translate('store_filter_form_stock_yes'),  
                                   '0' => $this->view->translate('store_filter_form_stock_no'),
                                   '2' => $this->view->translate('store_filter_form_stock_yesno'),),
            'validators'  => array(array('InArray', true, array(array('2', '1', '0'), true))),
            'value'       => ($data['stock']==='0' or $data['stock']==='1') ? $data['stock'] : 2 
        ));  
        $form->addElement($stock);
                     
        // Хит продаж  
        $hit = new Zend_Form_Element_Radio('hit', array(
            'label'       => $this->view->translate('store_filter_form_hit'),
            'multiOptions'=> array('1' => $this->view->translate('store_filter_form_hit_yes'),  
                                   '0'=>  $this->view->translate('store_filter_form_hit_no'),
                                   '2'=>  $this->view->translate('store_filter_form_hit_yesno'),),
            'validators'  => array(array('InArray', true, array(array('2', '1', '0'), true))),
            'value'       => ($data['hit']==='0' or $data['hit']==='1') ? $data['hit'] : 2 ,
        )); 
        $form->addElement($hit);
        
        // особые свойства товаров
        if(!empty($properties))
        {
            foreach($properties as $property)
            {
                $propertyName = 'property'.$property['property_id'];
                $propertiesNames[] = $propertyName;
                $propertyValues = array();
                if(!empty($property['values']))
                {
                    foreach($property['values'] as $val)
                    {
                        $propertyValues[$val['value']] = $val['value'];
                    }
                }
                $$propertyName = new Zend_Form_Element_MultiCheckbox($propertyName, array(
                    'label'        => $property['name'],
                    'multiOptions' => $propertyValues,
                    'value'        => (!empty($data[$propertyName])) ? $data[$propertyName] : $data[$propertyName] = array()
                ));
                $form->addElement($$propertyName);              
                
            }
            $this->view->properties_names = $propertiesNames;
        }        
         
        //  айди категории
        $cid = $form->createElement('hidden', 'cid')
            ->setValue($cidValue);
        $form->addElement($cid);

        // кнопка сабмита    
        $form->addElement('submit', 'filter_submit', 
                    array('label' => $this->view->translate('store_filter_form_submit')));
            
        // ошибки
        $this->_helper->FormErrors($errors, $form);
          
        return $form;
    }
    
/*------------------------------------------------------------------------------*/

    /**
    * Приватный метод для проверки айдишника категории
    */
    
    private function _checkCid()
    {
        $cid = $this->view->getParam('cid');

        if( $cid == false
            or $cid == null
            or empty($cid)
            or !isset($cid))
        {
            return 0;
        }
        else
        {
            return (int)$cid;
        }
    }

/*------------------------------------------------------------------------------*/

    /**
     * Метод для извлечения дочерних категорий.
     * В метод скармливается линейный массив из всех категорий
     * и айдишник родительской записи. 
     * 
     * @param $lineArray array
     * @param $parentId int
     * @param $treeArray array
     * @return array
     */
     
    private function _getChildren($lineArray = array(), 
                                $parentId = 0, 
                                $children = array())
    {         
        $children[] = $parentId;
        foreach($lineArray as $item)
        {                 
            if($parentId == (int)$item['pid'])  
            {                 
                $children[] = $item['id'];
                $this->_getChildren($lineArray, $item['id'], $children);
            }
        }        
        return $children; 
    }   

/*------------------------------------------------------------------------------*/
}
